import time
import logging
import traceback
import os
from psycopg2.errors import UndefinedTable

from tool_util import get_polardb_resource_info
from tool_util import create_conn
from tool_util import pg_exec
from tool_util import prometheus_push
from info_config import polardb_ro_delay_metrics_name
from info_config import polardb_delay_monitor_time_interval_min
from info_config import prometheus_url

# Get the current script path
script_path = os.path.dirname(os.path.abspath(__file__))
log_file = os.path.join(script_path, "polardb_ro_delay_monitor.log")

logging.basicConfig(
    filename=log_file,
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
)


def polardb_ro_delay_monitor(polar_info):
    print(polar_info)
    id = polar_info[0]
    name = polar_info[1]
    host = polar_info[2].get("host")
    port = polar_info[2].get("port")
    try:
        polardb_connect = create_conn(host, port, "postgres")
        sql = f"""SELECT MAX(replay_lag_in_ms) AS replay, physical_ins_name 
    FROM polar_gawr_collection.view_fact_pg_stat_replication 
    WHERE to_timestamp(time) > now() - interval '{polardb_delay_monitor_time_interval_min} minutes'  AND application_name like 'replica%'
    GROUP BY physical_ins_name;"""
        r = pg_exec(polardb_connect, sql)
        for i in r:
            replay = i[0]
            physical_ins_name = i[1]
            metric_data = f'{polardb_ro_delay_metrics_name}{{instanceId="{id}" ,resourceName="{name}",physicalInsName="{physical_ins_name}"}} {replay}'
            prometheus_push(prometheus_url, metric_data)

    except UndefinedTable as e:
        logging.info(
            f"{polar_info} The table view_fact_pg_stat_replication does not exist , awr is not enabled"
        )
    except Exception as e:
        logging.error("An error occurred: %s", traceback.format_exc())        
        logging.error(f"Error in polardb_ro_delay_monitor for {polar_info}")


def main():
    polardb_info_list = get_polardb_resource_info()
    while True:
        for polar_info in polardb_info_list:
            polardb_ro_delay_monitor(polar_info)

        time.sleep(polardb_delay_monitor_time_interval_min * 60)


if __name__ == "__main__":
    main()
